<template>
  <div class="waste-container">
    <div class="waste-left">
      <el-calendar ref="calendar" v-model="currentDate">
        <template #header="{ date }">
          <div class="el-calendar__title">{{ date }}</div>
          <div class="el-calendar__button-group">
            <el-button-group>
              <el-button size="small" @click="selectDate('prev-month')">
                <Icon icon="ep:arrow-left" />
              </el-button>
              <el-button size="small" type="primary" @click="selectDate('today')"> 今日 </el-button>
              <el-button size="small" @click="selectDate('next-month')">
                <Icon icon="ep:arrow-right" />
              </el-button>
            </el-button-group>
          </div>
        </template>
        <template #date-cell="{ data }">
          <div class="calendar-cell" @click="handleDayClick(data)">
            <span>{{ data.day.split('-')[2] }}</span>
            <div class="flex mt-4px gap-col-4px">
              <template v-for="(dot, index) in getShowDots(data.day)" :key="index">
                <span
                  class="calendar-dot"
                  :class="[dot.type]"
                  :style="{ backgroundColor: dot.color, width: dot.width }"
                ></span>
              </template>
            </div>
          </div>
        </template>
      </el-calendar>
      <div class="legend">
        <div class="legend-item">
          <span class="calendar-dot waste-dot"></span>
          <span>已登记</span>
        </div>
      </div>
    </div>

    <div class="waste-right">
      <ContentWrap class="!mb-0 flex-1">
        <div class="mb-10px">
          <el-alert
            v-if="!isToday"
            title="非当天数据仅可查看，不可编辑"
            type="warning"
            show-icon
            :closable="false"
          />
        </div>

        <el-tabs v-model="activeSchoolTab">
          <el-tab-pane
            v-for="school in schoolList"
            :key="school.value"
            :label="school.label"
            :name="school.value"
          >
            <el-tabs
              v-model="activeMealTab[school.value]"
              tab-position="left"
              v-if="formModel[school.value]"
            >
              <el-tab-pane
                v-for="meal in getStrDictOptions(DICT_TYPE.SCHOOL_MEAL_TYPE)"
                :key="meal.value"
                :label="meal.label"
                :name="meal.value"
              >
                <div class="h-482px">
                  <el-table
                    :data="getTableData(school.value, meal.value)"
                    height="100%"
                    :summary-method="getSummaries"
                    show-summary
                  >
                    <el-table-column prop="className" label="班级" width="180" />
                    <el-table-column
                      label="厨余量(kg)"
                      prop="wasteAmount"
                      class-name="h-43px !py-0"
                    >
                      <template #default="{ row }">
                        <el-input-number
                          v-if="isToday && row.classId"
                          v-model="row.wasteAmount"
                          :min="0"
                          controls-position="right"
                          class="w-full"
                        />
                        <span v-else>{{ formatWasteAmount(row.wasteAmount) }}</span>
                      </template>
                    </el-table-column>
                  </el-table>
                </div>

                <div class="mt-10px">
                  <el-form
                    :model="formModel[school.value][meal.value]"
                    label-position="top"
                    label-width="100px"
                    v-if="
                      isToday || (!isToday && formModel?.[school.value]?.[meal.value]?.wasteReason)
                    "
                  >
                    <el-form-item label="剩餐原因">
                      <el-input
                        v-if="isToday"
                        v-model="formModel[school.value][meal.value].wasteReason"
                        type="textarea"
                        placeholder="请输入剩餐原因"
                      />
                      <span v-else>{{ formModel[school.value][meal.value].wasteReason }}</span>
                    </el-form-item>
                  </el-form>
                </div>

                <div class="mt-10px" v-if="isToday">
                  <el-button
                    type="primary"
                    plain
                    @click="handleSave"
                    :disabled="loading"
                    v-hasPermi="['school:recipe-food-waste:update']"
                  >
                    <Icon icon="ep:circle-check" class="mr-5px" /> 保存
                  </el-button>
                </div>
              </el-tab-pane>
            </el-tabs>
          </el-tab-pane>
        </el-tabs>
      </ContentWrap>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { CalendarDateType, CalendarInstance } from 'element-plus'
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import { formatDate } from '@/utils/formatTime'
import { RecipeFoodWasteApi, RecipeFoodWaste } from '@/api/school/recipe/waste'
import { ClassesApi } from '@/api/school/classes'
import type { StringDictDataType } from '@/utils/dict'

/** 厨余登记 列表 */
defineOptions({ name: 'RecipeFoodWaste' })

// 定义日程点类型
interface WasteDot {
  type: string
  color: string
  width: string
}

// 定义班级厨余量数据类型
interface ClassWasteItem {
  id?: number
  classId: number
  className: string
  wasteAmount: number
}

// 定义表单数据类型
interface FormModel {
  mealType?: string
  wasteReason: string
}

const message = useMessage() // 消息弹窗

const calendar = ref<CalendarInstance>() // 日历组件实例
const currentDate: any = ref(new Date()) // 当前选中的日期
const monthData = ref<Record<string, boolean>>({}) // 月份数据，记录每天的厨余登记情况
const oldMonth = ref('') // 上一次查询的月份
const isToday = ref(true) // 是否为当天数据
const activeSchoolTab = ref('') // 当前激活的园区tab
const activeMealTab = ref<Record<string, string>>({}) // 各园区当前激活的餐别tab
const schoolList = ref<StringDictDataType[]>([]) // 园区列表
const classWasteData = ref<Record<string, Record<string, ClassWasteItem[]>>>({}) // 各园区各餐别的班级厨余量数据
const formModel = ref<Record<string, Record<string, FormModel>>>({}) // 各园区各餐别的表单数据

const loading = ref(true) // 列表的加载中
const allList = ref<RecipeFoodWaste[]>([]) // 所有数据，用于本地筛选
const queryParams = reactive({
  mealType: undefined,
  schoolCode: undefined,
  status: undefined,
  recordDate: [] as string[] // 修复类型问题
})

/** 格式化厨余量显示 */
const formatWasteAmount = (amount: number) => {
  if (!amount) return '0.00 kg'
  return `${amount.toFixed(2)} kg`
}

/** 获取表格数据（包括总计行） */
const getTableData = (schoolCode: string, mealType: string) => {
  const data =
    classWasteData.value[schoolCode] && classWasteData.value[schoolCode][mealType]
      ? classWasteData.value[schoolCode][mealType]
      : []
  return data
}

/** 获取总计方法 */
const getSummaries = (param: any) => {
  const { columns } = param
  const sums: string[] = []

  columns.forEach((column: any, index: number) => {
    if (index === 0) {
      sums[index] = '总计'
      return
    }

    if (column.property === 'wasteAmount') {
      // 获取当前激活的园区和餐别
      const schoolCode = activeSchoolTab.value
      const mealType = activeMealTab.value[schoolCode]

      // 获取当前园区和餐别的数据
      const data =
        classWasteData.value[schoolCode] && classWasteData.value[schoolCode][mealType]
          ? classWasteData.value[schoolCode][mealType]
          : []

      const values = data.map((item: any) => Number(item.wasteAmount))
      const total = values.reduce((prev, curr) => {
        const value = Number(curr)
        if (!isNaN(value)) {
          return prev + curr
        } else {
          return prev
        }
      }, 0)
      sums[index] = formatWasteAmount(total)
    } else {
      sums[index] = ''
    }
  })

  return sums
}

/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    // 如果有选择日期，则使用 getWasteByDay 接口获取数据
    if (queryParams.recordDate && queryParams.recordDate.length > 0) {
      // 获取第一个日期作为查询参数（格式：YYYYMMDD）
      const date = queryParams.recordDate[0].replace(/-/g, '')
      const data = await RecipeFoodWasteApi.getWasteByDay(date)
      // 保存所有数据用于本地筛选
      allList.value = data || []
    } else {
      // 如果没有选择日期，清空列表
      allList.value = []
    }

    // 检查是否为当天
    checkIsToday()

    // 加载班级厨余量数据
    await loadClassWasteData()
  } finally {
    loading.value = false
  }
}

/** 检查是否为当天 */
const checkIsToday = () => {
  if (!queryParams.recordDate || queryParams.recordDate.length === 0) {
    isToday.value = true
    return
  }

  const selectedDateStr = queryParams.recordDate[0]
  const today = new Date()
  const todayStr = formatDate(today, 'YYYY-MM-DD')
  isToday.value = selectedDateStr === todayStr
}

/** 加载班级厨余量数据 */
const loadClassWasteData = async () => {
  // 获取园区列表
  schoolList.value = getStrDictOptions(DICT_TYPE.SCHOOL_CODE) as StringDictDataType[]
  if (schoolList.value.length > 0 && !activeSchoolTab.value) {
    activeSchoolTab.value = schoolList.value[0].value
  }

  // 初始化各园区的活动餐别tab
  schoolList.value.forEach((school) => {
    if (!activeMealTab.value[school.value]) {
      activeMealTab.value[school.value] =
        getStrDictOptions(DICT_TYPE.SCHOOL_MEAL_TYPE)[0]?.value || ''
    }
  })

  // 获取所有班级列表
  const allClasses = await ClassesApi.getClassesSimpleList()

  // 按园区和餐别分组班级数据
  const groupedData: Record<string, Record<string, ClassWasteItem[]>> = {}
  schoolList.value.forEach((school) => {
    // 初始化园区数据
    if (!groupedData[school.value]) {
      groupedData[school.value] = {}
    }

    // 获取该园区的班级
    const schoolClasses = allClasses.filter((cls) => cls.schoolCode === school.value)

    // 为每个餐别初始化数据
    getStrDictOptions(DICT_TYPE.SCHOOL_MEAL_TYPE).forEach((meal) => {
      // 初始化数据，只显示班级名称，不显示园区名称
      groupedData[school.value][meal.value] = schoolClasses.map((cls) => {
        // 查找是否有对应的厨余登记数据，只使用stapleFoodWaste字段
        const wasteRecord = allList.value.find(
          (item) =>
            item.classId === cls.id &&
            item.schoolCode === school.value &&
            item.mealType === meal.value
        )
        return {
          id: wasteRecord?.id,
          classId: cls.id,
          className: cls.className, // 只显示班级名称，不显示园区名称
          wasteAmount: wasteRecord ? wasteRecord.stapleFoodWaste || 0 : 0
        }
      })
    })
  })

  classWasteData.value = groupedData

  // 更新表单数据（剩餐原因）
  updateFormData()
}

/** 更新表单数据（剩餐原因） */
const updateFormData = () => {
  // 初始化各园区各餐别的表单数据
  schoolList.value.forEach((school) => {
    if (!formModel.value[school.value]) {
      formModel.value[school.value] = {}
    }

    // 为每个餐别初始化表单数据
    getStrDictOptions(DICT_TYPE.SCHOOL_MEAL_TYPE).forEach((meal) => {
      if (!formModel.value[school.value][meal.value]) {
        formModel.value[school.value][meal.value] = {
          mealType: meal.value,
          wasteReason: ''
        }
      }
    })
  })

  // 如果有数据，按园区和餐别设置表单数据
  if (allList.value && allList.value.length > 0) {
    // 按园区和餐别分组数据
    const groupedData: Record<string, Record<string, RecipeFoodWaste[]>> = {}
    allList.value.forEach((item) => {
      if (item.schoolCode && item.mealType) {
        if (!groupedData[item.schoolCode]) {
          groupedData[item.schoolCode] = {}
        }
        if (!groupedData[item.schoolCode][item.mealType]) {
          groupedData[item.schoolCode][item.mealType] = []
        }
        groupedData[item.schoolCode][item.mealType].push(item)
      }
    })

    // 为每个园区和餐别设置表单数据
    Object.keys(groupedData).forEach((schoolCode) => {
      Object.keys(groupedData[schoolCode]).forEach((mealType) => {
        const mealData = groupedData[schoolCode][mealType]
        if (mealData.length > 0) {
          const firstRecord = mealData[0]
          if (formModel.value[schoolCode] && formModel.value[schoolCode][mealType]) {
            formModel.value[schoolCode][mealType].wasteReason = firstRecord.wasteReason || ''
          }
        }
      })
    })
  } else {
    // 如果没有数据，清空表单数据
    schoolList.value.forEach((school) => {
      getStrDictOptions(DICT_TYPE.SCHOOL_MEAL_TYPE).forEach((meal) => {
        if (formModel.value[school.value] && formModel.value[school.value][meal.value]) {
          formModel.value[school.value][meal.value].wasteReason = ''
        }
      })
    })
  }
}

/** 保存厨余量数据 */
const handleSave = async () => {
  if (!isToday.value) {
    message.warning('非当天数据仅可查看，不可编辑')
    return
  }

  try {
    // 为每个园区分别保存数据
    for (const schoolCode of Object.keys(classWasteData.value)) {
      // 为每个餐别保存数据
      for (const mealType of Object.keys(classWasteData.value[schoolCode])) {
        // 检查该园区该餐别是否有数据需要保存
        const hasWasteData = classWasteData.value[schoolCode][mealType].some(
          (cls) => cls.wasteAmount > 0
        )
        const hasWasteReason = formModel.value[schoolCode][mealType].wasteReason.trim() !== ''

        // 如果有数据需要保存
        if (hasWasteData || hasWasteReason) {
          // 构造提交数据
          const submitData: any = {
            schoolCode: schoolCode, // 传递对应园区字段
            mealType: mealType, // 传递对应餐别
            wasteReason: formModel.value[schoolCode][mealType].wasteReason, // 对应园区和餐别的剩餐原因
            recordDate: new Date(queryParams.recordDate[0]).getTime(), // 时间戳格式
            classWasteList: [] as any[]
          }

          // 收集该园区该餐别的班级厨余量数据
          classWasteData.value[schoolCode][mealType].forEach((cls) => {
            if (cls.wasteAmount > 0) {
              submitData.classWasteList.push({
                classId: cls.classId,
                mealType: mealType, // 传递对应餐别
                stapleFoodWaste: cls.wasteAmount,
                // 不再使用副食字段
                sideDishWaste: 0
              })
            }
          })

          // 调用创建/更新接口
          await RecipeFoodWasteApi.createRecipeFoodWaste(submitData)
        }
      }
    }

    message.success('保存成功')

    // 重新加载数据
    await getList()
  } catch (err) {
    message.error('保存失败: ' + (err as any).message || '未知错误')
  }
}

/** 处理日期选择 */
const handleDaySelect = (value: Date) => {
  const dateStr = formatDate(value, 'YYYY-MM-DD')
  getDayWasteData(dateStr)
}

/** 处理日期点击 */
const handleDayClick = (data: any) => {
  const date = new Date(data.day)
  handleDaySelect(date)
}

/** 获取指定日期的厨余登记 */
const getDayWasteData = async (day: string) => {
  // 更新查询参数中的日期
  queryParams.recordDate = [day, day] as string[] // 修复类型问题
  // 查询该日期的厨余登记
  await getList()
}

/** 监听日期变化 */
watch(currentDate, (val) => {
  const month = formatDate(val, 'YYYYMM')
  const day = formatDate(val, 'YYYY-MM-DD')

  // 如果月份变化了，重新获取月份数据
  if (oldMonth.value !== month) {
    getMonthData(month)
  }
  if (day) {
    handleDaySelect(new Date(day))
  }
})

/** 获取指定月份的厨余登记数据 */
const getMonthData = async (month: string) => {
  oldMonth.value = month
  try {
    // 调用 getWasteByMonth 接口获取当月厨余登记情况
    const data = await RecipeFoodWasteApi.getWasteByMonth(month)
    monthData.value = data || {}
  } catch (error) {
    console.error('获取月份厨余登记数据失败:', error)
    monthData.value = {}
  }
}

/** 获取日期显示的点 */
const getShowDots = (day: string): WasteDot[] => {
  const key = day.replace(/-/g, '')
  const dotArray: WasteDot[] = []

  // 如果当天有厨余登记，则显示绿色圆点
  if (monthData.value?.[key]) {
    dotArray.push({
      type: 'waste-dot',
      color: '#67C23A',
      width: '6px'
    })
  }

  return dotArray
}

/** 选择日期 */
const selectDate = (val: CalendarDateType) => {
  if (!calendar.value) return
  calendar.value.selectDate(val)
}

/** 初始化 **/
onMounted(() => {
  // 获取当前月份数据
  const month = formatDate(currentDate.value, 'YYYYMM')
  getMonthData(month)
  // 获取当前日期的厨余登记
  handleDaySelect(currentDate.value)
})
</script>

<style lang="scss" scoped>
.waste-container {
  display: flex;
  column-gap: 20px;
  min-height: $content-height;
}

.waste-left {
  width: 350px;
  padding: 15px;
  background-color: #fff;
  flex-shrink: 0;

  .legend {
    padding: 12px;
    margin-top: 12px;
    font-size: 14px;
    line-height: 1.5;
    color: #606266;
    text-align: center;

    .legend-item {
      display: inline-flex;
      align-items: center;
      gap: 4px;
      margin-right: 12px;

      &:last-child {
        margin-right: 0;
      }
    }
  }
}

.waste-right {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.calendar-cell {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.calendar-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-top: 2px;
  border-radius: 6px;
}

.calendar-dot.waste-dot {
  background-color: #67c23a;
}

:deep() {
  .el-calendar__header {
    padding: 2px;
  }

  .el-calendar__body {
    padding: 0;
  }

  .el-calendar-day {
    height: 50px;
    text-align: center;
  }

  .el-calendar-table td.is-selected {
    background-color: var(--el-color-primary-light-9) !important;
  }

  .el-tabs--left .el-tabs__header.is-left {
    margin-right: 10px;
  }

  .el-tabs--left .el-tabs__nav-wrap.is-left {
    margin-right: -1px;
  }
}
</style>
